home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / gfx / opal / OVLine11.lzh / ovlines.c < prev    next >
C/C++ Source or Header  |  1993-02-22  |  16KB  |  444 lines

  1. /* OVLINES.C        Version 1.1  
  2.         A Line drawing toy similar to PolyScope but for the OpalVision
  3.  INTRO:       
  4.     This hack draws lines in symmetry on the OpalVision screen.  It appears
  5.     no purpose, but is good eyecandy.  An alternative use would be a screen
  6.     blanker.     This hack is in its infancy, and in response to 
  7.     requests for this sort of drawing program.  It is based loosly on a program
  8.     called IToy in AMiga Basic ( about 1986), and is written in c compiled by
  9.     SAS brand  C compiler Version 6.02.  
  10.  
  11.  USE:
  12.         To use, type "ovlines" at the CLI prompt.  I did not bother to
  13.     make an Icon for it yet.  MAKE SURE FIRST THAT YOUR SCREENMODE IS EITHER
  14.     NTSC OR PAL.  If it is set to 800x600 or VGA results are unpredictible.
  15.     To exit, press and hold the mouse button.
  16.         A few options are added.  Typing "ovlines l" will latch the display
  17.     and leave the screen as of when exit was chosen as a backdrop to workbench.
  18.     Typing "ovlines s filename" will save the screen as an IFF24 file with that
  19.     name.  If you want it in another directory, specify the complete absolute
  20.     path.  I did not use JPEG since its optimized for full 24 bits and is not
  21.     efficient here, and the degradation is more apparent with this type of
  22.     picture, plus it takes significantly longer.  Even the IFF save uses all
  23.     24 bits, the pictures are actually larger than the screen! is better than
  24.     nothing.  
  25.         
  26.     
  27.  THEORY:
  28.  
  29.         Ovlines opens an 8 bit plane screen in Hires Overscan. It then algorith
  30.     matically generates a pallette (see PalGrad() ) that creates an array of colors
  31.     by stepping through them with different slopes.  I had tried totally random
  32.     palettes and a single gradient and this method seemed more pleasing than 
  33.     either.
  34.         The end points of the lines(x1,y1,x2,y2) are stepped by the interval
  35.     x1i,x2i, etc.  Four lines are created to connect to four points on the
  36.     screen.  The end points are clipped when they would get outside the screen
  37.     and the direction is reversed.  Each group is drawn with the next color
  38.     out of 256.  Color 0 is not used or affected, and that is the black back-
  39.     ground.  When all 255 colors are printed, new endpoints and intervals are
  40.     selected, and a different design is printed.  Every fourth run, the screen is
  41.     cleared, as it becomes too cluttered after that to make out any detail.
  42.     
  43.     
  44.              
  45.       
  46.     
  47.  LEGAL AND PURPOSE:   
  48.          This source is copyright 1993 Jim Boros, and may be redistibuted
  49.     by any means as long as this notice is intact.  Distribution is encouraged
  50.     by Fred Fish and the OpalVision BBS, and BIX.   It may be used in whole or
  51.     part for any noncommercial software product, especially a screen blanker.
  52.     You may alter it and redistribute
  53.     it, this is mainly for educational purposes, and it is hoped other program-
  54.     mers will add to it and repost.  If you alter this, please acknowledge
  55.     the origin plus any other programmers that contributed to it by leaving
  56.     these notices intact(you may add your credits for your additions and
  57.     modifications).   Use this at your own risk, I will not be responsible for 
  58.     any crashed machines or for any lost productivity or other damages caused
  59.     by this product(there shouldn't be any, but must cover my a**).
  60.      
  61.         OpalVision is a trademark of Opal Party Ltd. 
  62.         Amiga is a trademark of Commodore- Amiga, Inc.
  63.         Bars & Pipes is a trademark of Blue Ribbon Soundworks.
  64.             
  65.         This is distributed in request for these hacks, and this is to fill that
  66.     and to educate others on OpalVision programming.  It is hoped others use
  67.     this code this way, and add their own tricks and share these with other
  68.     OpalVision programmers.  Also, it is a piece of Eye Candy for Valentines
  69.     day and Easter.  
  70.         No set fee is requested for use of the program, however donations are
  71.     cheerfully accepted at the address below.  Future versions may be shareware
  72.     or part of a commercial package, but will be quite economical.    
  73.     
  74.  MY QUESTION:
  75.         I have tried to write programs with AMiga over Opal using DualDisplay
  76.     and AmigaPriority().  Every time it updated the Amiga overlay would flash.
  77.     Anyone have a workaround?           
  78.   
  79.     
  80.  FUTURE PLANS:    
  81.          If however, you wish to see a feature added and  are not a programmer
  82.     or if you are and have a question or comment about this, leave mail to me
  83.     (JimB) on OpalVIsion BBS or  jboros on BIX, or write to Borotec below.  
  84.           I will write an AGA version of this as soon as I get an AMiga
  85.     4000 or better computer.  If you can't wait for that, just donate one
  86.     and I'll write it and send you a disk of it.  Also, look for more 
  87.     OpalVision programs,  Modules for Bars&Pipes(Blue Ribbon Soundworks)
  88.     are being considered.   An algorithmic music composition program, MIDI Math,
  89.     is available from Borotec Inc, Box 17149, Euclid, Ohio  44117 for $29 
  90.     PPD.  This turns mathmatical equations into music compositions.  A version
  91.     to run with Bars & Pipes is under development, and it has not been determined
  92.     whether Borotec or Blue Ribbon will market.  
  93.           
  94.         
  95.         
  96.         
  97.         V1.10 J. Boros  2-13-93 */
  98.         
  99. #include <stdio.h>
  100. #include <stdlib.h>
  101. #include <string.h>
  102. #include <dos.h>
  103. #include <stddef.h>
  104. #include <math.h>
  105. #include <time.h>
  106. #include <opal/opallib.h>
  107. #include <graphics/gfxbase.h>
  108. #include <exec/memory.h>
  109. #include <hardware/custom.h>
  110. #include <proto/all.h>
  111.  
  112.  
  113. unsigned char *setpal(double hue, double sat,double lite, unsigned char *res);
  114. double  mag_blue(double), mag_green(double),mag_red(double);
  115. double  ITENO=255.0 ; /* 8 bit pallette instead of 6 per color */
  116.  
  117.  
  118.  
  119. void Clean_Up(char *,UBYTE); /* my prototypes go here */
  120. void RandPal(void),CycleColors(void);
  121. void PalGrad(short,short,short),PalSmooth(short,short);  
  122.   
  123. #define MAXCOLORS         256
  124. #define DISP_W  732 /* overscan screen */
  125. #define DISP_H  476 /* overscan height */
  126.  
  127. #define TRUE    1
  128. #define FALSE   0
  129. #define BAD     0
  130. #define OK      1
  131. #define RBMASK  0x0400  
  132. #define MAXMODE 2 /* increase as more modes are added */
  133.  
  134. #define colour  color   ; for programmers outside the USA
  135. #define Colour  Color
  136.  
  137. int clk[2]; /* for reading time */      
  138. struct OpalBase *OpalBase = NULL;
  139. struct OpalScreen *OScrn;
  140.  
  141. /*  Joystick and Mouse primitive stuff.
  142.  
  143.     Yes, I bang the hardware but this is not for video, and is read only */
  144.  
  145. __far extern struct Custom custom; /* for registers */
  146.  
  147. __far UBYTE *Button = (UBYTE *)0xbfe001;    /* Nasty */
  148. __far UWORD *RButton= (UWORD *)0xdff016; /* read right button */
  149.         /* bit 10, use dff016 for right */
  150. #define RIGHT   custom.joy1dat & 2
  151. #define LEFT    custom.joy1dat & 0x200
  152. #define UP     ( custom.joy1dat & 1 )    
  153. #define DOWN   ( custom.joy1dat & 0x100) 
  154. #define FIRE    (*Button & 0x80)
  155.        
  156.         
  157. main(argc,argv)
  158. int argc;
  159. char **argv;
  160. {
  161. long scm;
  162. short mode,i,x1,y1=323,x2,y2=77;
  163. short x1i,y1i,x2i,y2i; /* drawing variables */
  164. UBYTE c=1,ci,inch,argf,pm=1;
  165.     i=0;
  166.     mode=0; /* default to lines */
  167.     argf=1; /* normal */
  168.     timer(clk); /* get time */
  169.     srand(clk[0]+clk[1]); /*reseed randomizer */
  170.             
  171.     printf("OVlines V1.10 Copyright J. Boros 1993 \n");
  172.     printf("Usage: ovlines [pm] [option] [filename] \n");
  173.     printf("Where pm =0 for random, 1 for ramped, 2 for smooth hues \n");
  174.     printf("Hold Right Mouse Button a few sec to change Mode \n");
  175.     x1i=x2i=y1i=y2i=9; /* default increment */
  176.     OpalBase = (struct OpalBase *) OpenLibrary ("opal.library",0L);
  177.     if (OpalBase==0L)
  178.         Clean_Up ("Can't open opal.library\n",10);
  179.     OScrn = NULL;
  180.     scm = ILACE24 | HIRES24 | OVERSCAN24 | PALMAP24 | PLANES8 ;
  181.        OScrn = OpenScreen24(scm) ; /* open an OpalVision Screen */
  182.     if ( !OScrn) Clean_Up( "Cannot open OV Screen ",22);
  183.     StopUpdate24();
  184.     AutoSync24(FALSE);
  185.     OVPriority();
  186.     ci =  (UBYTE) *argv[1];
  187.     if ( (argc >=1 ) && isdigit(ci) ){
  188.          pm= ci-48; /* if a number entered use */
  189.          argf=2; } /* look one higher for argument */
  190.              
  191.     switch (pm) {/* decide what to do with palette */
  192.         case 0: RandPal(); break; /* have utterly random palette */      
  193.         case 1: PalGrad(13,5,47); /* psuedo randomize palette */ break;
  194.         case 2 : PalSmooth(98,60); /* create smooth palette */ break;
  195.     }
  196.     UpdatePalette24();
  197.     RegWait24();
  198.     
  199.   /*   memcpy(&OpalScreen->Palette[0],&Colours[0][0],768); */
  200.   
  201.      
  202.     while (*Button &0x040)  { /* try and cycle colours until button pressed */
  203.         c++; 
  204.         if (((c&127)==0) || ( !FIRE && !(c&3))   ) { /* after each 256 line sets change pattern */
  205.             c=1; /* don't draw bkg color */
  206.             x1= rand() % DISP_W;
  207.             x2=rand()  %DISP_W; 
  208.             timer(clk); /* get time */
  209.             srand(clk[0]+clk[1]); /*reseed randomizer */
  210.             y1=rand() % DISP_H;                   
  211.             y2=rand()%  DISP_H; /* randimize */
  212.             x1i=x2i=rand() &0x0F | 1;
  213.             y1i=y2i=rand() &0x07 | 1;
  214.            
  215.             /* maybe I'll rand the intervals */
  216.             i++;
  217.           /*  inch=getch(); */
  218.              if ( !(i&7) ) {ClearQuick24(); /* clear screen every 8th run */
  219.             UpdatePalette24(); i=0;
  220.                  }
  221.  
  222.         }    
  223.         
  224.         x1+=x1i;    y1+=y1i;
  225.         x2-=x2i;    y2-=y2i; /* add the increments */
  226.         if ( UP ) { y1+=10;  y2 += 10; }/* Steer it W Joystick JB 2-16 */
  227.         if ( DOWN ) { y1-=10; y2 -=10; }
  228.         if ( LEFT ) { x1-= 14; x2-=14; }
  229.         if ( RIGHT) { x1+=14; x2+= 14; }             
  230.         /* clip values, keep them on screen */            
  231.           if (x1 <0) { x1 =0;           x1i =x1i *(-1); }
  232.         if (x1 >DISP_W) {    x1 =DISP_W-x1i;         x1i =x1i *(-1); }
  233.         if (y1 <0) {   y1 =0;              y1i =y1i *(-1); }
  234.         if (y1 >DISP_H) { y1 =DISP_H-y1i;           y1i =y1i *(-1); }
  235.         if (x2 <0) {   x2 =0;             x2i =x2i *(-1); }
  236.         if (x2 >DISP_W) { x2 =DISP_W-x2i;            x2i =x2i *(-1); }
  237.         if (y2 <0) {  y2 =0;               y2i =y2i *(-1); }
  238.         if (y2 >DISP_H) { y2 =DISP_H-y2i;           y2i =y2i *(-1); }
  239.         OScrn->Pen_R=256-c; /* set colour to draw  NOTE WE ONLY NEED USE RED!*/    
  240.         /* now draw them */
  241.         CycleColors();
  242.         switch ( mode) { /* decide several shapes */
  243.             case 0 :
  244.                 DrawLine24(OScrn,x1,y1,x2,y2);    
  245.                 DrawLine24(OScrn,x1,DISP_H-y1,x2,DISP_H-y2);    
  246.                 DrawLine24(OScrn,DISP_W-x1,y1,DISP_W-x2,y2);    
  247.                  DrawLine24(OScrn,DISP_W-x1,DISP_H-y1,DISP_W-x2,DISP_H-y2); 
  248.                  break;
  249.             case 1 : /* try boxes */
  250.                 RectFill24(OScrn,min(x1,x2),min(y1,y2),max(x1,x2),max(y1,y2));
  251.      
  252.                 if ( c <255) OScrn->Pen_R++; /* try incr pens */
  253.             /*    RectFill24(OScrn,DISP_W-max(x1,x2),DISP_H-max(y1,y2),
  254.                     DISP_W-min(x1,x2),DISP_H-min(y1,y2) ); */
  255.                     break; 
  256.             case 2 : /* ellipses? */
  257.                 DrawEllipse24(OScrn, (x1+x2)/2,(y1+y2)/2, abs(x1-x2)/2,abs(y1-y2)/2);
  258.                 DrawEllipse24(OScrn,DISP_W-((x1+x2)/2),DISP_H-((y1+y2)/2), abs(x1-x2)/2,abs(y1-y2)/2);
  259.                 break;
  260.         }   
  261.         if ((!(*RButton & RBMASK)) && (!(c &3))) { /* debounsed rmb in*/
  262.             mode++;
  263.             if (mode >MAXMODE) mode=0; /* limit if gets too high */
  264.         }             
  265.         WaitTOF();                
  266.         Refresh24(); /* update screen and give OS a breather for any tasks */
  267.         Delay(1);
  268.     } /* end of draw loop */
  269.     if ( argc > argf) { /* we typed some extra stuff! */
  270.         switch ((UBYTE) *argv[argf] ) { /* if we typed a command use disp as bakdrop*/
  271.           case 'l' : /* latch display and use as backdrop */                
  272.             AmigaPriority ();
  273.             DualDisplay24 ();
  274.             AutoSync24 (FALSE); /* try turn off autosync */
  275.             Delay (1);
  276.             LatchDisplay24 (TRUE);
  277.             break;
  278.           case 's' : /* save as IFF file using name */
  279.             if(argc>(argf+1))
  280.              x1=SaveIFF24(OScrn,argv[argf+1],NULL,NULL); /* save as iff24 */
  281.             Clean_Up("Attemped to save IFF",x1);  
  282.         }
  283.                 
  284.     }        
  285.  
  286.  
  287.     Clean_Up(" Normal Exit",0);
  288. }    
  289.  
  290. void RandPal()
  291. {
  292. int i,j; /* fill palette with RANDOM or pseudorandom colours */
  293.     for(i=3; i<(MAXCOLORS*3); i++){ 
  294.         j=rand(); 
  295.         OScrn->Palette[i]= (UBYTE) ((j>>3) & 0x0FF); /* try LSB's */
  296.         
  297.     }       
  298.  
  299. }       
  300.  
  301. void PalGrad(rm,gm,bm)
  302. short rm,gm,bm;
  303. { /* gradients depending on values entered as 'mod' values for ea colour */
  304. int i; 
  305.     for(i=1;i< MAXCOLORS; i++){
  306.         OScrn->Palette[i*3]   =(i*rm) &0x0ff+200 ;  
  307.         OScrn->Palette[i*3+1] =(i*gm) &0x0ff ;
  308.         OScrn->Palette[i*3+2] =(i*bm) &0x0ff ;     /* appear to cycle */
  309.           }
  310.     
  311. }            
  312. void PalSmooth(short s,short v)
  313. {
  314. int i;
  315.     for(i=1; i<MAXCOLORS; i++)
  316.       setpal((double)i/256.0,s/100.0,v/100.0,&OScrn->Palette[i*3]);
  317.  /* make a very smooth transition of hue, with high saturation */
  318. }    
  319.  
  320. void CycleColors() {
  321. UBYTE rl,gl,bl;    
  322.     /* cycle colors, plays 'musical' registers.  Screen structure is
  323.     global, as one slip here invites Mr. GURU 
  324.     WE DO NOT CYCLE COLOR 0, it is the black background */
  325.     
  326.         rl=OScrn->Palette[765]; /* get old top values  R*/
  327.         gl=OScrn->Palette[766]; /* get old top values  G*/
  328.         bl=OScrn->Palette[767]; /* get old top values B*/
  329.         memmove(&OScrn->Palette[6],&OScrn->Palette[3],762);
  330.         OScrn->Palette[3]=rl; /* leave color 0 alone! */
  331.         OScrn->Palette[4]=gl;
  332.         OScrn->Palette[5]=bl;
  333.         UpdatePalette24(); /* make it regiter on OV */              
  334. }
  335.  
  336. void Clean_Up(error,ExitVal)
  337. UBYTE ExitVal;
  338. char *error;
  339. {
  340.     if (OpalBase) {
  341.         AmigaPriority();
  342. /*        SingleDisplay24(); */
  343.  
  344.         if (OScrn) {
  345.             CloseScreen24();
  346.             OScrn = NULL;
  347.         }
  348.  
  349.         CloseLibrary((struct Library *)OpalBase);
  350.         OpalBase = NULL;
  351.     }
  352.     printf(" %s \n",error); /* tell why we quit! */
  353.     exit(ExitVal);
  354. }
  355.  
  356.  
  357.  
  358. /* conversion from HSV to RGB */
  359. /* derived from Computer Applications Journal Oct/Nov 92 */
  360. /* call setpal below to use, other routines here are subparts of setpal
  361.   hue,sat,lite are double floating point between 0 and 1.
  362.   res is a pointer to the red entry in the palette */
  363.   
  364. unsigned char *setpal(double hue, double sat,double lite, unsigned char *res)
  365. {
  366. double  red,green,blue;
  367. double  red1,gren1,blu1,euh,sat0; 
  368.     
  369.         if (hue <= 0.5) euh=hue+0.5; /* hue compliment */
  370.         else            euh=hue-0.5;
  371.         sat0=2.0*lite+min((-4.0*lite) + 2.0, 0.0); 
  372.         sat0=max(sat0,0.0); /* max sat= f(lite) */
  373.         sat0=min(sat0,1.0);
  374.  
  375.         blue=mag_blue(hue);
  376.         blue=max(blue,0.0);
  377.         blue=min(blue,1.0);
  378.         
  379.         blu1=mag_blue(euh);
  380.         blu1=max(blu1,0.0);
  381.         blu1=min(blu1,1.0);
  382.         
  383.         blue= ITENO * lite *(blue + ( 1.0 - sat*sat0) *blu1);
  384.         
  385.         
  386.         green=mag_green(hue);
  387.         green=max(green,0.0);
  388.         green=min(green,1.0);
  389.         
  390.         gren1=mag_green(euh);
  391.         gren1=max(gren1,0.0);
  392.         gren1=min(gren1,1.0);
  393.         
  394.         green= ITENO * lite *(green + ( 1.0 - sat*sat0) *gren1);
  395.         
  396.  
  397.         red=mag_red(hue);
  398.         red=max(red,0.0);
  399.         red=min(red,1.0);
  400.         
  401.         red1=mag_red(euh);
  402.         red1=max(red1,0.0);
  403.         red1=min(red1,1.0);
  404.         
  405.         red= ITENO * lite *(red + ( 1.0 - sat*sat0) *red1);
  406.         *res=     (unsigned char) red; /* stash results in BYTE buffer */
  407.         *(res+1) =(unsigned char) green;
  408.         *(res+2) =(unsigned char) blue;
  409.         
  410.  
  411.         return(res);
  412. }
  413.  
  414.  
  415. double mag_red(double x) /* switch red and blue for OpalVision Compat */
  416. {
  417. double result;
  418.     result=(max(0.3333-x,0.0)+min(x-0.16667,0.0)+max(x-0.6667,0.0)+
  419.         min(0.8333-x,0.0))/0.1666; 
  420.     return(result);
  421.     
  422. }
  423.  
  424. double mag_green(double x)
  425. {
  426. double result;
  427.     result=( x+min(0.1667-x,0.0)+min(0.5-x,0.0)+max(x-0.6667,0.0))/0.1667;
  428.     return(result);
  429. }
  430. double mag_blue(double x)
  431. {
  432. double result;
  433.     result=(max(x-0.3333,0.0)+min(0.5-x,0.0)+min(0.8333-x,0.0))/0.1667;
  434.     return(result);
  435. }        
  436.  
  437.  
  438.             
  439.  
  440.    
  441.  
  442.    
  443.  
  444.